let logger = require("pomelo-logger").getLogger(__filename);
let announcementCreator = require("../entities/announcement").create;
let announcementLoader = require("../entities/announcement").loadFromDocument;
let DateUtil = require("../../utils/dateUtil");

let AnnouncementService = function (app) {
    this.app = app;
    this.announcements = [];
    this.nextAnnouncementId = 0;
};

AnnouncementService.prototype.initialize = function () {
    let announcementDao = this.app.get("announcementDao");
    let maxAnnouncementId = 0;
    //load from mongo
    announcementDao.findAllAnnouncements(documents => {
        for(let document of documents) {
            let announcement = announcementLoader(document);
            this.announcements.push(announcement);
            if(announcement.id >= maxAnnouncementId) {
                maxAnnouncementId = announcement.id;
            }
        }
        this.nextAnnouncementId = maxAnnouncementId + 1;
        this.sort();
    });
};

AnnouncementService.prototype.getAnnouncements = function () {
    return this.announcements;
};

AnnouncementService.prototype.getAnnouncementById = function (id) {
    for(let announcement of this.announcements) {
        if(id === announcement.id) {
            return announcement;
        }
    }
    return null;
};

AnnouncementService.prototype.updateAnnouncement = function (id, title, content, startTime,
                                                             endTime, callback) {
    let announcementDao = this.app.get("announcementDao");
    if(this.contains(id)) {
        callback(null);
        return;
    }
    for(let announcement of this.announcements) {
        if(id === announcement.id) {
            announcementDao.update(id, title, content, startTime, endTime, result => {
                if(!result || result.result.ok != 1) {
                    logger.info(`updateAnnouncement error. document null`);
                    callback(null);
                    return;
                }
                announcement.title = title;
                announcement.content = content;
                announcement.startTime = startTime;
                announcement.endTime = endTime;
                this.sort();
                callback(announcement);
            });
        }
    }
};

AnnouncementService.prototype.addAnnouncement = function (title, content, startTime, endTime, callback) {
    let announcementDao = this.app.get("announcementDao");
    let announcement = announcementCreator(this.nextAnnouncementId, title, content, startTime, endTime);
    announcementDao.insertOne(announcement.toBSON(), result => {
        if(!result || result.result.ok != 1) {
            logger.info(`addAnnouncement error. id empty`);
            callback(null);
            return;
        }
        this.announcements.push(announcement);
        this.sort();
        this.nextAnnouncementId ++;
        callback(announcement);
    });
};

AnnouncementService.prototype.deleteAnnouncementById = function (id, callback) {
    let announcementDao = this.app.get("announcementDao");
    announcementDao.deleteById(id, result => {
        if(!result || result.ok != 1) {
            logger.info(`deleteAnnouncementById error. id empty`);
            callback(null);
            return;
        }
        let announcements = [];
        this.announcements.forEach(announcement => {
            if(announcement.id !== id) {
                announcements.push(announcement);
            }
        });
        this.announcements = announcements;
        this.sort();
        callback(id);
    });
};

AnnouncementService.prototype.getEffectAnnouncementsJSON = function () {
    let serializeAnnouncements = [];
    let now = DateUtil.nowMS();
    this.announcements.forEach(announcement => {
        if(now > announcement.startTime && now < announcement.endTime) {
            serializeAnnouncements.push(announcement.toJSON());
        }
    });
    return serializeAnnouncements;
};

AnnouncementService.prototype.toJSON = function () {
    let serializeAnnouncements = [];
    this.announcements.forEach(announcement => {
        serializeAnnouncements.push(announcement.toJSON());
    });
    return serializeAnnouncements;
};

AnnouncementService.prototype.contains = function (id) {
    for(let announcement of this.announcements) {
        if(announcement.id == id) {
            return
        }
    }
};

AnnouncementService.prototype.sort = function () {
    this.announcements.sort(function (s1, s2) {
        return s1.id < s2.id ? 1 : -1;
    });
};

module.exports.create = function (app) {
    return new AnnouncementService(app);
};
